﻿using OT.HikiSecureCenterApis.Req;
using OT.HikiSecureCenterApis.Res;
using OT.HikiSecureCenterApis.Service.OneCard.Res;

namespace OT.HikiSecureCenterApis.Service.OneCard
{
    /// <summary>
    /// 一卡通应用服务 --> 梯控管理
    /// </summary>
    public partial class OneCardService
    {
        #region 梯控功能接口
        /// <summary>
        /// 查询梯控历史事件信息 /api/ecs/v1/access_events/search
        /// 该接口可以查询发生在电梯上的人员出入事件和设备事件，支持多个维度来查询，支持按时间、人员、设备、卡号、事件类型五个维度来查询；
        /// 其中按事件类型来查询的方式，如果查询不到事件，存在两种情况，一种是该类型的事件没有发生过，所以查询不到，还有一种情况，该类型的事件发生过，
        /// 但是由于梯控管理组件对该事件类型订阅配置处于关闭状态，所以不会存储该类型的事件，导致查询不到，对于这种情况，需要到系统配置->梯控管理组件中，将该事件类型的订阅配置打开。
        /// 事件发生时间:eventTime指事件在设备上产生的时间,平台接收事件时间:receiveTime指平台接收到事件的时间,两者可能有几秒的差别,如果用该接口获取事件来做考勤,
        /// 应该通过receiveTime作为条件获取事件信息,保存在本地,然后通过receiveTime做考勤,这样可以保证数据不会丢失。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="page">必填，页码、页大小、开始时间、结束时间</param>
        /// <param name="deviceCodes">非必填，设备id组(最大支持500个设备集搜索,多个用”,”隔开)， 查询梯控控制器列表v2接口获取</param>
        /// <param name="personIds">非必填，人员id组(人员Id通过查询人员信息接口获取，最大支持1000个人员搜索,多个用”,”隔开)， 获取人员列表v2 接口获取</param>
        /// <param name="cardNos">非必填，卡片组(最大支持1000张卡片搜索,多个用”,”隔开), 获取卡片列表接口可以获取</param>
        /// <param name="eventTypes">非必填，事件类型，10进制，多个事件类型用”,”隔开，参考附录D.2.4.1 梯控管理事件类型
        /// https://open.hikvision.com/docs/479a2e6a09fd495f82e3362cd46ca87f?curNodeId=479a2e6a09fd495f82e3362cd46ca87f#e2efad2e
        /// </param>
        /// <param name="sort">非必填，排序字段，支持personName、deviceName、eventTime，填写排序的字段名称</param>
        /// <param name="order">非必填，升/降序，指定排序字段是使用升序（asc）还是降序（desc）</param>
        /// <returns><see cref="ResCCSDevice"/></returns>
        public async Task<ResParameter<ResTurnPage<ResAccessEvent>>?> AccessEventSearchAsync(ReqPageDate page, string deviceCodes = null, string personIds = null,
            string cardNos = null, string eventTypes = null, string sort = null, string order = null) =>
          await SecureCenterApis.PostAsync<ResTurnPage<ResAccessEvent>>("/api/ecs/v1/access_events/search", 1.3, new
          {
              startTime = page?.startTime,
              endTime = page?.endTime,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10,
              deviceCodes = deviceCodes,
              personIds = personIds,
              cardNos = cardNos,
              eventTypes = eventTypes,
              sort = sort,
              order = order
          });
        #endregion

        #region 梯控网管接口
        /// <summary>
        /// 获取梯控主机在线状态 /api/nms/v1/online/ladder_controller/get
        /// 根据条件获取梯控主机在线状态接口
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="page">非必填，页码、页大小</param>
        /// <param name="regionId">非必填，区域id , 分页获取区域列表接口可以获取</param>
        /// <param name="ip">非必填，设备ip</param>
        /// <param name="indexCodes">非必填，梯控设备列表，最大500， 查询梯控控制器列表v2接口获取</param>
        /// <param name="status">非必填，状态 1: 在线 0: 离线 -1:未检测</param>
        /// <param name="includeSubNode">非必填，是否包含下级（若regionId为空，则该参数不起作用）1: 包含 0: 不包含</param>
        /// <returns><see cref="ResOnline"/></returns>
        public async Task<ResParameter<ResPageData<ResOnline>>?> GetAdderControllerOnlineAsync(ReqPage page = null, string regionId = null, string ip = null,
           IList<string> indexCodes = null, string status = null, string includeSubNode = null) =>
          await SecureCenterApis.PostAsync<ResPageData<ResOnline>>("/api/nms/v1/online/ladder_controller/get", 1.3, new
          {
              regionId = regionId,
              ip = ip,
              indexCodes = indexCodes,
              status = status,
              includeSubNode = includeSubNode,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10
          });
        /// <summary>
        /// 获取梯控读卡器在线状态 /api/nms/v1/online/ladder_card_reader/get
        /// 根据条件获取梯控读卡器在线状态接口
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="page">非必填，页码、页大小</param>
        /// <param name="regionId">非必填，区域id , 分页获取区域列表接口可以获取</param>
        /// <param name="indexCodes">非必填，梯控设备列表，最大500， 查询梯控控制器列表v2接口获取</param>
        /// <param name="status">非必填，状态 1: 在线 0: 离线 -1:未检测</param>
        /// <param name="includeSubNode">非必填，是否包含下级（若regionId为空，则该参数不起作用）1: 包含 0: 不包含</param>
        /// <returns><see cref="ResOnline"/></returns>
        public async Task<ResParameter<ResPageData<ResOnline>>?> GetLadderCardReaderOnlineAsync(ReqPage page = null, string regionId = null,
           IList<string> indexCodes = null, string status = null, string includeSubNode = null) =>
          await SecureCenterApis.PostAsync<ResPageData<ResOnline>>("/api/nms/v1/online/ladder_card_reader/get", 1.3, new
          {
              regionId = regionId,
              indexCodes = indexCodes,
              status = status,
              includeSubNode = includeSubNode,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10
          });
        #endregion

        #region 梯控资源接口
        /// <summary>
        /// 查询梯控控制器列表v2 /api/resource/v2/ecsDevice/search
        /// 根据条件查询目录下有权限的梯控控制器列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="req">参数</param>
        /// <returns><see cref="ResEcsDevice"/></returns>
        public async Task<ResParameter<ResPageData<ResEcsDevice>>?> EcsDeviceSearchAsync(ReqSearch req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResEcsDevice>>("/api/resource/v2/ecsDevice/search", 1.4, req);
        /// <summary>
        /// 查询梯控楼层列表v2 /api/resource/v2/floor/search
        /// 根据条件查询目录下有权限的梯控楼层列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="req">参数</param>
        /// <returns><see cref="ResFloor"/></returns>
        public async Task<ResParameter<ResPageData<ResFloor>>?> FloorSearchAsync(ReqSearch req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResFloor>>("/api/resource/v2/floor/search", 1.4, req);
        /// <summary>
        /// 查询梯控读卡器列表 /api/resource/v1/ladderCardReader/search
        /// 查询目录下有权限的梯控读卡器列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="req">参数</param>
        /// <returns><see cref="ResLadderCardReader"/></returns>
        public async Task<ResParameter<ResPageData<ResLadderCardReader>>?> LadderCardReaderSearchAsync(ReqSearch req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResLadderCardReader>>("/api/resource/v1/ladderCardReader/search", 1.3, req);
        /// <summary>
        /// 增量获取梯控控制器数据 /api/resource/v1/ecsDevice/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。其中开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="page">必填，页码、页大小、开始时间、结束时间</param>
        /// <returns><see cref="ResEcsDevice"/></returns>
        public async Task<ResParameter<ResPageData<ResEcsDevice>>?> EcsDeviceTimeRangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResEcsDevice>>("/api/resource/v1/ecsDevice/timeRange", 1.4, page);
        /// <summary>
        /// 增量获取梯控楼层数据 /api/resource/v1/floor/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。其中开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="page">必填，页码、页大小、开始时间、结束时间</param>
        /// <returns><see cref="ResFloor"/></returns>
        public async Task<ResParameter<ResPageData<ResFloor>>?> FloorTimeRangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResFloor>>("/api/resource/v1/floor/timeRange", 1.4, page);
        /// <summary>
        /// 增量获取梯控读卡器数据 /api/resource/v1/ladderCardReader/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。其中开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.5及以上版本</remarks>
        /// <param name="page">必填，页码、页大小、开始时间、结束时间</param>
        /// <returns><see cref="ResLadderCardReader"/></returns>
        public async Task<ResParameter<ResPageData<ResLadderCardReader>>?> LadderCardReaderTimeRangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResLadderCardReader>>("/api/resource/v1/ladderCardReader/timeRange", 1.5, req);
        #endregion
    }
}
